
package nsga;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.StringTokenizer;

public class VRPTW implements Problema
{
    private ClienteVRPTW[] clientes;
    private double[][] tiempos;
    private double capacity;

    public VRPTW(ClienteVRPTW[] clientes, double[][] tiempos, double capacity)
    {
        this.clientes = clientes;
        this.tiempos=tiempos;
        this.capacity = capacity;
    }
    
    public int getTipo()
    {
        return 2;
    }

    public void setFitness(Individuo individuo)
    {
        individuo.setFitness(null);
    }

    public int getLength()
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public double getCapacity()
    {
        return capacity;
    }

    public ClienteVRPTW[] getClientes()
    {
        return clientes;
    }

    public double[][] getTiempos()
    {
        return tiempos;
    }
    
    public Individuo[] cruzar(Individuo individuo1, Individuo individuo2)
    {
        IndividuoVRPTW[] result=new IndividuoVRPTW[2];
        result[0]=new IndividuoVRPTW(clientes, tiempos, capacity);
        result[1]=new IndividuoVRPTW(clientes, tiempos, capacity);
        CamionVRPTW[] camiones1=((IndividuoVRPTW)individuo1).getCamiones();
        int[] camionesProbados1=new int[camiones1.length];
        int cantidadDigitos1=(int)Math.pow(10, String.valueOf(camiones1.length).length());
        CamionVRPTW[] camiones2=((IndividuoVRPTW)individuo2).getCamiones();
        int[] camionesProbados2=new int[camiones2.length];
        int cantidadDigitos2=(int)Math.pow(10, String.valueOf(camiones2.length).length());
        boolean turno=false;
        while(!result[0].isAllClientesVisited())
        {
            if(!turno)
            {
                do
                {
                    if(isAllCamionesTested(camionesProbados1))
                    {
                        result[0].fillWithRandomCamiones();
                        break;
                    }
                    else
                    {
                        int rand;
                        do
                        {
                            rand=(int)(Math.random()*cantidadDigitos1);
                        }
                        while(rand>=camionesProbados1.length);
                        if(camionesProbados1[rand]==0)
                        {
                            camionesProbados1[rand]=1;
                            if(result[0].addCamion(camiones1[rand]))
                            {
                                turno=true;
                                break;
                            }
                        }
                    }
                }
                while(true);
            }
            else
            {
                do
                {
                    if(isAllCamionesTested(camionesProbados2))
                    {
                        result[0].fillWithRandomCamiones();
                        break;
                    }
                    else
                    {
                        int rand;
                        do
                        {
                            rand=(int)(Math.random()*cantidadDigitos2);
                        }
                        while(rand>=camionesProbados2.length);
                        if(camionesProbados2[rand]==0)
                        {
                            camionesProbados2[rand]=1;
                            if(result[0].addCamion(camiones2[rand]))
                            {
                                turno=false;
                                break;
                            }
                        }
                    }
                }
                while(true);
            }
        }
        for(int i=0;i<camionesProbados1.length;i++)
        {
            camionesProbados1[i]=0;
        }
        for(int i=0;i<camionesProbados2.length;i++)
        {
            camionesProbados2[i]=0;
        }
        turno=false;
        while(!result[1].isAllClientesVisited())
        {
            if(!turno)
            {
                do
                {
                    if(isAllCamionesTested(camionesProbados2))
                    {
                        result[1].fillWithRandomCamiones();
                        break;
                    }
                    else
                    {
                        int rand;
                        do
                        {
                            rand=(int)(Math.random()*cantidadDigitos2);
                        }
                        while(rand>=camionesProbados2.length);
                        if(camionesProbados2[rand]==0)
                        {
                            camionesProbados2[rand]=1;
                            if(result[1].addCamion(camiones2[rand]))
                            {
                                turno=true;
                                break;
                            }
                        }
                    }
                }
                while(true);
            }
            else
            {
                do
                {
                    if(isAllCamionesTested(camionesProbados1))
                    {
                        result[1].fillWithRandomCamiones();
                        break;
                    }
                    else
                    {
                        int rand;
                        do
                        {
                            rand=(int)(Math.random()*cantidadDigitos1);
                        }
                        while(rand>=camionesProbados1.length);
                        if(camionesProbados1[rand]==0)
                        {
                            camionesProbados1[rand]=1;
                            if(result[1].addCamion(camiones1[rand]))
                            {
                                turno=false;
                                break;
                            }
                        }
                    }
                }
                while(true);
            }
        }
        IndividuoVRPTW.isIndividuoValido(result[0]);
        IndividuoVRPTW.isIndividuoValido(result[1]);
        return result;
    }
    
    public static VRPTW main(String args)throws Exception
    {
        BufferedReader bufferedReader=new BufferedReader(new FileReader(args));
        bufferedReader.readLine();
        int length=Integer.parseInt(bufferedReader.readLine());
        bufferedReader.readLine();
        double capacity=Double.parseDouble(bufferedReader.readLine());
        bufferedReader.readLine();
        int[] numeroCliente=new int[length];
        double[][] coordenadas=new double[length][2];
        double[][] tiempos=new double[length][length];
        double[] demandas=new double[length];
        double[] tiemposApertura=new double[length];
        double[] tiemposCierre=new double[length];
        double[] tiemposServicio=new double[length];
        ClienteVRPTW[] clientes=new ClienteVRPTW[length];
        for(int i=0;i<length;i++)
        {
            StringTokenizer stringTokenizer=new StringTokenizer(bufferedReader.readLine());
            numeroCliente[i]=Integer.parseInt(stringTokenizer.nextToken());
            coordenadas[i][0]=Double.parseDouble(stringTokenizer.nextToken());
            coordenadas[i][1]=Double.parseDouble(stringTokenizer.nextToken());
            for(int j=0;j<i;j++)
            {
                double tiempo=Math.sqrt(Math.pow((coordenadas[i][0]-coordenadas[j][0]),2)+Math.pow((coordenadas[i][1]-coordenadas[j][1]),2));
                tiempos[j][i]=tiempo;
                tiempos[i][j]=tiempo;
            }
            demandas[i]=Double.parseDouble(stringTokenizer.nextToken());
            tiemposApertura[i]=Double.parseDouble(stringTokenizer.nextToken());
            tiemposCierre[i]=Double.parseDouble(stringTokenizer.nextToken());
            tiemposServicio[i]=Double.parseDouble(stringTokenizer.nextToken());
            clientes[i]=new ClienteVRPTW(numeroCliente[i],demandas[i], tiemposApertura[i], tiemposCierre[i], tiemposServicio[i]);
        }
        return new VRPTW(clientes, tiempos, capacity);
    }
    
    private static boolean isAllCamionesTested(int[] camiones)
    {
        for(int i=0;i<camiones.length;i++)
        {
            if(camiones[i]==0)
            {
                return false;
            }
        }
        return true;
    }
}
